import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @Author Stringzhua
 * @Date 2024/10/31 11:21
 * description:
 */
public class ReentrantLockDemo03 {
    public static void main(String[] args) {
        //公共锁
        ReentrantLock lock = new ReentrantLock();
        Condition condition = lock.newCondition();

        //打印1~52的数字线程
        new Thread(new Number(lock, condition)).start();

        //打印A~Z的字母线程
        new Thread(new Character(lock, condition)).start();
    }
}

class Number implements Runnable {
    private ReentrantLock lock;
    private Condition condition;

    public Number(ReentrantLock lock, Condition condition) {
        this.lock = lock;
        this.condition = condition;
    }

    @Override
    public void run() {
        //当前线程争夺cpu执行权,争夺一个公共的object对象锁
        final ReentrantLock lock = this.lock;
        lock.lock();
        try {
            for (int i = 1; i <= 52; i++) {
                //输出数字
                System.out.print(i);
                //①唤醒当前object对象锁等待区中的其他线程(字母线程[wait-->runnable])
                this.condition.signalAll();
                if (i % 2 == 0) {
                    try {
                        //②让当前线程(数字线程)进入等待区(runnable-->wait)并释放锁
                        this.condition.await();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        } finally {
            lock.unlock();
        }
    }
}


class Character implements Runnable {
    private ReentrantLock lock;
    private Condition condition;

    public Character(ReentrantLock lock, Condition condition) {
        this.lock = lock;
        this.condition = condition;
    }

    @Override
    public void run() {
        //当前线程争夺cpu执行权,争夺一个公共的object对象锁
        final ReentrantLock lock = this.lock;
        lock.lock();
        try {
            for (char i = 'A'; i <= 'Z'; i++) {
                //输出字母
                System.out.print(i + " ");
                //①唤醒当前object对象锁等待区中的其他线程(数字线程[wait-->runnable])
                this.condition.signalAll();
                if (i < 'Z') {
                    //②让当前线程(字母线程)进入等待区(runnable-->wait)并释放锁
                    try {
                        this.condition.await();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        } finally {
            lock.unlock();
        }
    }
}

